import render from "./render"
import util from "../base/util"
import {createScopedThreejs} from '../libs/threejs-miniprogram'
import {registerTextureLoader} from '../libs/texture_loader'

export default class renderWebgl extends render {
  constructor() {
    super()
    this.THREE = createScopedThreejs({context: canvas.getContext("webgl", {alpha: true})})
    this.renderer = new this.THREE.WebGLRenderer({canvas: canvas, antialias: true})
    this.renderer.setSize(canvas.width, canvas.height)
    this.renderer.sortObjects = false

    this.THREE.canvas = wx
    registerTextureLoader(this.THREE) //https://blog.csdn.net/geshu12138/article/details/105862436
    this.loader = new this.THREE.TextureLoader()
    this.scene = new this.THREE.Scene()

    this.aspect = canvas.width / canvas.height
    this.cameraOrth = new this.THREE.OrthographicCamera(- this.aspect, this.aspect, 1, - 1, 1, 100)
    this.cameraOrth.position.z = 5
    this.cameraPrsp = new this.THREE.PerspectiveCamera(60, this.aspect, 1, 100)
    this.cameraPrsp.position.set(1, 1, 5)

    this.texture_cache = {} //image_src_uuid, texture
    this.imgsrc_texture = {} //image_src_uuid, obj
    this.obj_imgsrc = {} //obj, image_src_uuid
  }
  testDrawText(){
    if (!this.txt_cvs){
      this.txt_cvs = wx.createCanvas()
      this.txt_cvs.height = 100
      this.txt_ctx = this.txt_cvs.getContext('2d')
      this.txt_ctx.fillStyle = 'rgba(0, 0, 0, 0)'
      this.txt_ctx.fillRect(0, 0, this.txt_cvs.width, this.txt_cvs.height)
      this.txt_ctx.fillStyle = 'rgba(255, 0, 0, 1)'
      this.txt_ctx.font = '90px Arial'
      this.txt_ctx.fillText('lalalal', (this.txt_cvs.width - this.txt_ctx.measureText('lalalal').width) * 0.5, 80)

      let t = new this.THREE.CanvasTexture(this.txt_cvs)
      t.minFilter = this.THREE.LinearFilter
      t.needsUpdate = true      
      let mtl = new this.THREE.SpriteMaterial({map: t, transparent: true})
      let obj = new this.THREE.Sprite(mtl)
      let dx = 60, dy = 60, dw = 60, dh = 30
      //obj.position.set((dx + dw / 2 - canvas.width * 0.5) / canvas.width, - (dy + dh / 2 - canvas.height * 0.5) / canvas.width, 3)
      //obj.scale.set(dw / canvas.width, dh / canvas.width)
      obj.position.z = 3

      this.scene.add(obj)
    }
  }

  clearImage(image){
    if (this.imgsrc_texture[image.uuid]){
        /*util.request({
          api: "astray/testClient",
          data: {
            info: "clear: " + image.uuid}})*/
        //util.request2({type: "Test", info: "clear1: " + image.uuid})
      let obj = this.imgsrc_texture[image.uuid]
      this.scene.remove(obj)
      delete this.obj_imgsrc[obj]
      delete this.imgsrc_texture[image.uuid]
    }
  }

  async drawImage0(image, dx, dy, dw, dh, dz = 1, force_update = null, newTexture = false){
    if (force_update){
      this.clearImage(image)
    }
    if (!this.imgsrc_texture[image.uuid]){
      if (this.texture_cache[image.uuid] && !newTexture){
        var txt = this.texture_cache[image.uuid]
      }else{
        this.imgsrc_texture[image.uuid] = true
        txt = await this.loader.load(image.src)
      }
      this.texture_cache[image.uuid] = txt
      /*util.request({
        api: "astray/testClient",
        data: {
          info: "add: " + image.uuid}})*/
      //util.request2({type: "Test", info: "add: " + image.uuid})
      txt.minFilter = this.THREE.LinearFilter
      let mtl = new this.THREE.SpriteMaterial({map: txt, transparent: true})
      let obj = new this.THREE.Sprite(mtl)
      obj.position.set((dx + dw / 2 - canvas.width * 0.5) / canvas.width, - (dy + dh / 2 - canvas.height * 0.5) / canvas.height / this.aspect, dz)
      obj.scale.set(dw / canvas.width, dh / canvas.height / this.aspect)
        
      this.scene.add(obj)
      this.obj_imgsrc[obj.uuid] = image.uuid
      this.imgsrc_texture[image.uuid] = obj
    }
  }
  async update(callback){
    if (callback){
      await callback(this.THREE, this.scene, this.loader, this.cameraPrsp)
      this.renderer.render(this.scene, this.cameraPrsp)
    }else
      this.renderer.render(this.scene, this.cameraOrth)
  }
  clearRect(x, y, w, h, first){
    if (first){
      while(this.scene.children.length > 0){ 
        let obj = this.scene.children[0]

        /*util.request({
          api: "astray/testClient",
          data: {
            info: "clear: " + this.obj_imgsrc[obj.uuid]}})*/
        //util.request2({type: "Test", info: "clear0: " + this.obj_imgsrc[obj.uuid]})
        delete this.imgsrc_texture[this.obj_imgsrc[obj.uuid]]
        delete this.obj_imgsrc[obj.uuid] 
        this.scene.remove(obj)
      }
    }
  }
  fillText(text, x, y, maxWidth){

  }
  setFont(fillStyle, font){

  }
}